package runtime

import (
	"fmt"
	"runtime"
	"sync"
)

func change() {
	doneCh := make(chan bool)
	defer close(doneCh)
	go func(s string) {
		defer catchErr()
		cur := 0
		for i := 0; i < 1000; i++ {
			fmt.Println(s)
			cur++
		}
		fmt.Printf("current : %v\n", cur)
		doneCh <- true
	}("world")

	// 主协程
	// 切一下，再次分配任务
	// 协程序都会被中断
	runtime.Gosched()
	fmt.Println("hello")
	<-doneCh
}

func catchErr() {
	if err := recover(); err != nil {
		fmt.Println("go ", err)
	}

}

func exit(i int) {
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer catchErr()
		defer wg.Done()
		defer fmt.Println("A.defer")
		perfect(i, &wg)
		fmt.Println("A")
	}()
	wg.Wait()
}

func perfect(i int, wg *sync.WaitGroup) {
	defer wg.Done()
	defer fmt.Println("B.defer")
	wg.Add(1)
	// 结束协程
	if i == 0 {
		runtime.Goexit()
	}
	defer fmt.Println("C.defer")
	fmt.Println("B")
}

func printFor100(m int) {
	var wg sync.WaitGroup
	wg.Add(1)
	go func(n int) {
		defer catchErr()
		for i := 0; i < n; i++ {
			printFor(i, &wg)
		}
	}(m)
	wg.Wait()
}

func printFor(i int, wg *sync.WaitGroup) {
	defer wg.Done()
	defer fmt.Printf("num %v \n", i)
	if i == 100 {
		runtime.Goexit()
	}
	wg.Add(1)
}
